#!/usr/bin/env bash

#
# enode发布脚本
#
# 本地拉取代码 -> 编译程序 -> 新程序推送上传到节点更新服务
#
# 发布推送测试节点命令: bash node_release.sh -b test --release=true --env=test
# 发布推送分批节点更新10%: bash node_release.sh -b test --release=true --env=test --gray=10
#
#

set -e
PROJECT_NAME=estore
#本地工作目录
WORK_DIR=$(cd $(dirname $0); pwd)

PROJECT_PATH=${WORK_DIR}/.work/${PROJECT_NAME}


GIT_REPO="git@git.guanjieai.com:estore/estore.git"
#节点更新服务器推送地址
NODE_SERVER="http://upgrade.guanjieai.com/pkg/release"

ARG_B=""
ARG_C=""
ARG_T=""
ARG_E="test"
ARG_ONLY_BUILD="0"
ARG_RELEASE="false"
ARG_GRAY="0"
ARG_OS_ARCH=""


function build_darwin_amd64() {
  if [[ "${ARG_OS_ARCH}" != "darwin_amd64" ]]; then
    return
  fi
  eNodeBin="${WORK_DIR}/.tmp/enode/${1}-darwin-amd64"
  if [ ! -f "${eNodeBin}" ]; then
    CGO_ENABLED=1 GOOS=darwin GOARCH=x86_64 ${PROJECT_PATH}/scripts/release.sh build -v -o ${eNodeBin}
    if [ ! -f "${eNodeBin}" ]; then
      show err "${eNodeBin}编译构建失败"
      return
    fi
    show notice "[${eNodeBin}]编译构建完成"
  else
    show notice "[${eNodeBin}]已编译存在"
  fi
  #推送服务器
  release ${2} darwin amd64 ${3} ${eNodeBin}
}

function build_linux_amd64() {
  if [[ "${ARG_OS_ARCH}" != "" && "${ARG_OS_ARCH}" != "linux_amd64" ]]; then
    return
  fi
  eNodeBin="${WORK_DIR}/.tmp/enode/${1}-linux-amd64"
  if [ ! -f "${eNodeBin}" ]; then
    CGO_ENABLED=1 GOOS=linux GOARCH=amd64 ${PROJECT_PATH}/scripts/release.sh build -v -o ${eNodeBin}
    if [ ! -f "${eNodeBin}" ]; then
      show err "${eNodeBin}编译构建失败"
      return
    fi
    show notice "[${eNodeBin}]编译构建完成"
  else
    show notice "[${eNodeBin}]已编译存在"
  fi
  #推送服务器
  release ${2} linux amd64 ${3} ${eNodeBin}
}

function build_linux_arm64() {
  if [[ "${ARG_OS_ARCH}" != "" && "${ARG_OS_ARCH}" != "linux_arm64" ]]; then
    return
  fi
  eNodeBin="${WORK_DIR}/.tmp/enode/${1}-linux-arm64"
  if [ ! -f "${eNodeBin}" ]; then
    CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=/usr/local/musl/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc ${PROJECT_PATH}/scripts/release_arm.sh build -v -o ${eNodeBin} .
    if [ ! -f "${eNodeBin}" ]; then
      show err "${eNodeBin}编译构建失败"
      return
    fi
    show notice "[${eNodeBin}]编译构建完成"
  else
    show notice "[${eNodeBin}]已编译存在"
  fi
  #推送服务器
  release ${2} linux arm64 ${3} ${eNodeBin}
}

function build() {
  if [[ ! -d "${PROJECT_PATH}" ]] || [[ ! -d "${PROJECT_PATH}/.git" ]]; then
    rm -rf "${PROJECT_PATH}"
    git clone $GIT_REPO $PROJECT_PATH
  fi
  cd $PROJECT_PATH && git checkout main && git pull
  if [ ! -z "${ARG_B}" ]; then
    git checkout ${ARG_B} && git pull
  elif [ ! -z "${ARG_C}" ]; then
    git checkout ${ARG_C}
  elif [ ! -z "${ARG_T}" ]; then
    git checkout ${ARG_T}
  fi

  COMMIT=$(git rev-parse HEAD)
  if [[ "$(git diff --stat)" != '' ]] || [[ -n "$(git status -s)" ]]; then
    echo "Changes detected, building a development version"
    COMMIT="${COMMIT}-dirty"
  fi

  releaseVersion="v0.0.0"
  if git describe --tags --exact-match --match "v[0-9]*.[0-9]*.[0-9]*"; then
    releaseVersion=$(git describe --tags --exact-match --match "v[0-9]*.[0-9]*.[0-9]*")
  fi
  PACKAGE_NAME="enode-${releaseVersion}-${COMMIT}"

  cd ${PROJECT_PATH}/enode/cmd/enode

  #构建linux amd64
  build_linux_amd64 ${PACKAGE_NAME} ${releaseVersion} ${COMMIT}
  #构建linux arm64
  build_linux_arm64 ${PACKAGE_NAME} ${releaseVersion} ${COMMIT}
  #构建 arm64
  build_darwin_amd64 ${PACKAGE_NAME} ${releaseVersion} ${COMMIT}
}

function show() {
  case "${1}" in
  succ)
    shift && echo -e "\033[32m${@}\033[0m"
    ;;
  err)
    shift && echo -e "\033[31m${@}\033[0m"
    exit 1
    ;;
  notice)
    shift && echo -e "\033[33m${@}\033[0m"
    ;;
  *)
    echo $*
    ;;
  esac
}

function packZip() {
  nodeBin="${1}"
  dir=$(dirname nodeBin)
  enode="${dir}/enode"
  mv ${nodeBin} ${enode}
  serviceFile="${PROJECT_PATH}/scripts/enode.service"
  updateFile="${PROJECT_PATH}/scripts/enode_update.py"
  upgradeService="${PROJECT_PATH}/scripts/enode_upgrade_timer.service"
  upgradeServiceTimer="${PROJECT_PATH}/scripts/enode_upgrade_timer.timer"
  zipFile="${nodeBin}.zip"
  set +e
  output=`zip "${zipFile}" -j "${serviceFile}" "${updateFile}" "${upgradeService}" "${upgradeServiceTimer}" "${enode}"`
  if [ $? != 0 ];then
    echo "打包程序失败: zip "${zipFile}" -j "${serviceFile}" "${updateFile}" "${upgradeService}" "${upgradeServiceTimer}" "${enode}""
    echo $output
    exit 1
  fi
  set -e
  rm -f ${enode}
  echo ${zipFile}
}

#推送到包更新管理服务器
function release() {
  zipFile=`packZip ${5}`
  curl \
    -F "version=${1}" \
    -F "env=${ARG_E}" \
    -F "os=${2}" \
    -F "arch=${3}" \
    -F "gray=${ARG_GRAY}" \
    -F "release=${ARG_RELEASE}" \
    -F "commit_id=${4}" \
    -F "file=@${zipFile}" \
    ${NODE_SERVER}
  echo ""
}

function main() {
  set -- $(getopt -o b:t:c:e: -l branch:,tag:,commit:,env:,build:,release:,gray:,osarch: -n ${0} -u -- "$@")
  #解析参数
  while true; do
    case "${1}" in
    -b | --branch)
      ARG_B="${2}"
      shift
      ;;
    -t | --tag)
      ARG_T="$2"
      shift
      ;;
    -c | --commit)
      ARG_C="$2"
      shift
      ;;
    -e | --env)
      ARG_E="$2"
      shift
      ;;
    --gray)
      ARG_GRAY="${2}"
      shift
      ;;
    --osarch)
      ARG_OS_ARCH="${2}"
      shift
      ;;
    --build)
      ARG_ONLY_BUILD="1"
      shift
      ;;
    --release)
      ARG_RELEASE="true"
      shift
      ;;
    --)
      shift
      break
      ;;
    *)
      echo "${1} is not option"
      ;;
    esac
    shift
  done

  if [ "${ARG_E}" == "prod" ]; then
    read -p "请注意，目前操作的是生产环境，你确定吗？确定请输入[yes]!" yes
    if [ "${yes}" != "yes" ]; then
      show err "生产环境发布失败！"
      exit
    fi
    if [ "${ARG_T}" == "" ]; then
      show notice "生产环境只支持tag版本发布，请[-t version]输入要发布的tag版本！"
      exit
    fi
    ARG_B=""
  fi
  echo -e "环境[\033[31m${ARG_E}\033[0m]开始执行..."

  #编译项目
  build
  if [ "${ARG_ONLY_BUILD}" == "1" ]; then
    show succ "编译完成退出"
    exit 0
  fi
}

main $@
